package com.yunquan.ohana.ui.calendar.sync

import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.CalendarContract
import android.provider.Settings
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.yunquan.ohana.R
import com.yunquan.ohana.BR
import com.yunquan.ohana.base.ui.BaseActivity
import com.yunquan.ohana.databinding.ActivitySyncBinding
import com.yunquan.ohana.dialog.TipDialog
import java.util.Locale
import androidx.core.net.toUri
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yunquan.ohana.entity.EventEntity
import com.yunquan.ohana.entity.FramesDataManager
import com.yunquan.ohana.entity.ScheduleModel
import com.yunquan.ohana.entity.ScheduleModelVo
import com.yunquan.ohana.ui.calendar.event.dialog.EventSyncDialog
import com.yunquan.ohana.ui.scan.ScanActivity
import com.yunquan.ohana.utils.DateUtils
import com.yunquan.ohana.utils.StringUtils
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId
import java.util.Date

class SyncActivity : BaseActivity<ActivitySyncBinding, SyncViewModel>() {

    private val CALENDAR_PERMISSIONS = arrayOf(
        android.Manifest.permission.READ_CALENDAR,
        android.Manifest.permission.WRITE_CALENDAR
    )

    override fun initContentView(savedInstanceState: Bundle?): Int {
        return R.layout.activity_sync
    }

    override fun initVariableId(): Int {
        return BR.syncViewModel
    }

    override fun initParam() {
        super.initParam()
        Locale.setDefault(Locale("en"))
        // 设置背景颜色
        window.statusBarColor = ContextCompat.getColor(this, R.color.white)
        // 设置文字颜色（true = 黑色文字，false = 白色文字）
        val controller = WindowInsetsControllerCompat(window, window.decorView)
        controller.isAppearanceLightStatusBars = true
    }

    override fun initData(savedInstanceState: Bundle?) {
        super.initData(savedInstanceState)
        val bundle = intent.extras
        bundle?.let {
            viewModel!!.mDeviceId = it.getString("deviceId")
            viewModel!!.mRoleId = it.getString("roleId")
        }
        if (checkCalendarPermission()) {
            readCalendarEvents()
        } else {
            requestCalendarPermission()
        }
    }

    override fun initViewObservable() {
        super.initViewObservable()
        viewModel!!.ui.observe(this) { syncToDevice() }
    }

    private fun checkCalendarPermission(): Boolean {
        return CALENDAR_PERMISSIONS.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestCalendarPermission() {
        ActivityCompat.requestPermissions(this, CALENDAR_PERMISSIONS, 1001)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 1001) {
            if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                // 权限全部授予
                readCalendarEvents()
            } else {
                val dialog = TipDialog(this)
                dialog.setTitle(getString(R.string.insufficient_permissions))
                dialog.setMessage(getString(R.string.calendar_permissions_are_required_to_synchronize_local_calendars))
                dialog.setRightBtn(getString(R.string.btn_exit))
                dialog.setLeftBtn(getString(R.string.go_settings))
                dialog.setOnDialogClickListener(object : TipDialog.OnDialogClickListener() {
                    override fun onLeftClick() {
                        super.onLeftClick()
                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
                            data = "package:$packageName".toUri()
                        }
                        startActivity(intent)
                    }

                    override fun onRightClick() {
                        super.onRightClick()
                        finish()
                    }
                })
            }
        }
    }

    @SuppressLint("Range")
    private fun readCalendarEvents() {
        showLoading()
        // 1️⃣ 查询事件表
        val uri = CalendarContract.Events.CONTENT_URI
        val projection = arrayOf(
            CalendarContract.Events._ID,
            CalendarContract.Events.CALENDAR_ID,
            CalendarContract.Events.TITLE,
            CalendarContract.Events.DESCRIPTION,
            CalendarContract.Events.DTSTART,
            CalendarContract.Events.DTEND,
            CalendarContract.Events.EVENT_LOCATION,
            CalendarContract.Events.ALL_DAY,
        )
        val now = LocalDateTime.now()
        // 2️⃣ 可选：按时间范围过滤
        val startTime = now.withDayOfMonth(1)
            .with(LocalTime.MIN)
            .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
        val endTime = now.withDayOfMonth(now.toLocalDate().lengthOfMonth())
            .with(LocalTime.MAX)
            .atZone(ZoneId.systemDefault())
            .toInstant().toEpochMilli()
        val selection = "(${CalendarContract.Events.DTSTART} >= ?) AND (${CalendarContract.Events.DTEND} <= ?)"
        val selectionArgs = arrayOf(startTime.toString(), endTime.toString())

        val cursor = contentResolver.query(
            uri,
            projection,
            selection,
            selectionArgs,
            "${CalendarContract.Events.DTSTART} ASC"
        )
        val dataList = mutableListOf<ScheduleModelVo>()
        cursor?.use {
            while (it.moveToNext()) {
                val id = it.getLong(it.getColumnIndex(CalendarContract.Events._ID))
                val title = it.getString(it.getColumnIndex(CalendarContract.Events.TITLE))
                val desc = it.getString(it.getColumnIndex(CalendarContract.Events.DESCRIPTION))
                val start = it.getLong(it.getColumnIndex(CalendarContract.Events.DTSTART))
                val end = it.getLong(it.getColumnIndex(CalendarContract.Events.DTEND))
                val location = it.getString(it.getColumnIndex(CalendarContract.Events.EVENT_LOCATION))
                val allDay = it.getInt(it.getColumnIndex(CalendarContract.Events.ALL_DAY))
                val bean = ScheduleModelVo(
                    deviceId = viewModel!!.mDeviceId,
                    title = title,
                    startTime = Date(start).time / 1000,
                    endTime = Date(end).time / 1000,
                    allDay = allDay,
                    repeats = "0",
                    deviceRoleDtoList = mutableListOf(mutableMapOf("deviceId" to viewModel!!.mDeviceId, "roleId" to viewModel!!.mRoleId)),
                )
                dataList.add(bean)
            }
        }
        viewModel!!.items.clear()
        dataList.forEach {
            viewModel!!.items.add(
                SyncItemViewModel(viewModel!!, it)
            )
        }
        dismissLoading()
    }

    private fun syncToDevice() {
        val deviceList = FramesDataManager.instance.getData().filter {
            it.id != viewModel!!.mDeviceId
        }.toMutableList()
        val dialog = EventSyncDialog(
            context = this,
            mActivityResult,
            devices = deviceList,
        )
        dialog.setOnBindDeviceListener { code ->
            viewModel!!.bindFrames(code)
        }
        dialog.setOnSelectDeviceListener { devices ->
            viewModel!!.syncToDevice(devices)
        }
        dialog.show()
    }

    // 这里处理返回结果
    private val mActivityResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == ScanActivity.RESULT_CODE) {
            // 扫描二维码返回
            val bundle = result.data?.extras
            val text = bundle?.getString("text")
            text?.let {
                viewModel!!.bindFrames(it)
            }
        }
    }
}